package cn.aiweiyi.qingjing.coupon.gateway.filter;


import com.google.common.util.concurrent.RateLimiter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;

/**
 * @author 青衿
 * @Date 2020/11/13 9:55
 * 执行限流的前置过滤器
 * 限流的过滤器
 **/
@Slf4j
@Component
public class RateLimitFilter extends AbstractPreZuulFilter {
    String ERROR_MSG = "ERROR:获取访问令牌失败! 请求被限流";
    //根据guava库提供的限流工具类,创建一个限流器对象
    //2.0表示每秒过去2个令牌,基于令牌桶算法实现
    RateLimiter rateLimiter = RateLimiter.create(2.0);


    @Override
    protected Object cRun() {
        HttpServletRequest request = context.getRequest();
        if (rateLimiter.tryAcquire()) {
            log.info("获取访问令牌成功!");
            return success();//放行,允许访问微服务,过滤器链继续执行
        } else {
            //为了便于运维统计,把被限流的请求路径记录到日志中
            log.error(ERROR_MSG + ":%s", request.getRequestURI());
            //403是HTTP协议的禁止访问状态码
            return fail(403, ERROR_MSG);
        }
    }

    @Override
    public int filterOrder() {
        return 1;//早于TokenFilter,看业务需要可以灵活调整
    }
}
